# -*- coding:utf-8 -*-
import os,sys
import re
import traceback
import time
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), os.pardir))
import supeanut_config
from CommonLib.mylog import mylog
from CommonLib.PageCrawler.UrlAccess import UrlAccess
from CommonLib.StockTool import StockTool


'''
作者：supeanut
创建时间：2016-xx-xx xx:xx:xx
功能描述：
	xxx
	xxxxx
相关配置：
	supeanut_config.XXX
历史改动：
	2016-xx-xx: xxxxxx
'''
class SinaAPI:
	# init what
	def __init__(self):
		self.timeout = supeanut_config.SINA_API_TIMEOUT
		self.base_url = supeanut_config.SINA_BASIC_URL
		self.try_max = supeanut_config.SINA_API_TRYMAX
		self.codec = supeanut_config.SINA_API_ENCODE
		self.api_return_listlen = supeanut_config.SINA_API_LENGTH
		# 接口返回字段提取股票代码
		self.stockcode_RE = re.compile(r'(?<=var hq_str_)[a-z]{2}[0-9]{6}')
		self.stock_tool = StockTool()
		
	# 完整url访问并解码，尝试一次
	# 返回body部分（unicode）
	def access_sina(self, url):
		log = mylog('DataAPI.SinaAPI.access_sina', None)
		accessor = UrlAccess()
		accessor.set_timeout(self.timeout)
		flag, response = accessor.get_response(url, 'GET')
		if flag is False:
			log.exception('Exception Logged')
			return False, response
		try:
			body = response['body']
			# 解码
			body = body.decode(self.codec)
		except:
			log.exception('Exception Logged')
			return False, 'decodec failed, or noformal response'
		return True, body

	# 根据新浪接口定制的访问字串
	# 输入'stock' or 'index', ['300033', ...]，输出"sz300033,sh600000"
	# 格式均为utf8
	def list2str(self, stock_index, stock_code_list):
		stock_code_str = ''
		for stock_code in stock_code_list:
			if stock_index == 'stock':
				stock_market = self.stock_tool.get_stock_market(stock_code)
			if stock_index == 'index':
				stock_market = self.stock_tool.get_sina_index_market(stock_code)
			stock_code_str += (stock_market + stock_code + ',')
		# 除去尾端逗号
		stock_code_str = stock_code_str[:-1]
		# 拼接完整URL
		base_url = self.base_url
		complete_url = base_url + stock_code_str
		return complete_url
	
	
	# 处理接口返回str数据，返回标准日内数据格式dict（utf-8）
	def process_response(self, response_str):
		log = mylog('DataAPI.SinaAPI.process_response', None)
		stockinfo_list = response_str.split('\n')
		result_dict = {}
		for stockinfo in stockinfo_list:
			if stockinfo.find("var") < 0:
				continue
			# 过滤错误股票代码返回的结果
			if stockinfo.find("\"\"") >= 0:
				continue
			stockcode = self.stockcode_RE.search(stockinfo)
			if stockcode is None:
				log.warning('can not find stockcode in response: %s' % stockinfo)
				continue
			stockcode = stockcode.group(0)
			info_str = stockinfo.split('\"')[1]
			info_list = info_str.split(',')
			if len(info_list) != self.api_return_listlen:
				log.warning('invalid length of sina api return : %s' % info_str)
				continue
			stockcode = stockcode.encode('utf-8')
			result_dict[stockcode] = {}
			result_dict[stockcode]['open'] = info_list[1].encode('utf-8')
			#result_dict[stockcode]['last_close'] = info_list[2].encode('utf-8')
			result_dict[stockcode]['cur_price'] = info_list[3].encode('utf-8')
			result_dict[stockcode]['cur_high'] = info_list[4].encode('utf-8')
			result_dict[stockcode]['cur_low'] = info_list[5].encode('utf-8')
			result_dict[stockcode]['vol_stock'] = info_list[8].encode('utf-8')
			result_dict[stockcode]['vol_capital'] = info_list[9].encode('utf-8')
			result_dict[stockcode]['date'] = info_list[-3].encode('utf-8')
			result_dict[stockcode]['time'] = info_list[-2].encode('utf-8')
		return result_dict

	# 行情获取
	# INPUT: 'stock'or'index', ['300033', ...]
	# OUTPUT:
	def cur_hq(self, stock_index, stock_code_list):
		log = mylog('DataAPI.SinaAPI.cur_stock_hq', None)
		# 获得完整url
		access_str = self.list2str(stock_index, stock_code_list)
		# 访问接口，尝试多次
		try_count = 0
		try_flag = False
		while try_count < self.try_max:
			try_count += 1
			flag, response = self.access_sina(access_str)
			if flag is True:
				try_flag = True
				break
			# 访问失败，休10秒
			time.sleep(10)
		if try_flag is False:
			log.error('reach try max, no resonse')
			return False, 'reach try max, no resonse'
		result_dict = self.process_response(response)
		return True, result_dict
		
if __name__ == '__main__':
	obj = SinaAPI()
	print obj.cur_hq('stock', ['000001', '002824', '603239'])
	#print obj.cur_hq('index', ['000001', '000300', '399001', '399005', '399006'])
